package com.atguigu.nio.groupchart;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class GroupChartServer {

    private Selector selector;
    private ServerSocketChannel listenSocketChannel;
    private final static int PORT = 6667;

    public GroupChartServer() {

        try {
            selector = Selector.open();
            listenSocketChannel = ServerSocketChannel.open();
            listenSocketChannel.socket().bind(new InetSocketAddress(PORT));
            listenSocketChannel.configureBlocking(false);
            listenSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 监听
    public void listen() {
        System.out.println("监听现场：" + Thread.currentThread().getName());
        try {
            while (true) {
                int select = selector.select(2000);
                if (select > 0) {
                    Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
                    while (keyIterator.hasNext()) {
                        SelectionKey key = keyIterator.next();
                        // 监听到accept
                        if (key.isAcceptable()) {
                            SocketChannel socketChannel = listenSocketChannel.accept();
                            socketChannel.configureBlocking(false);
                            socketChannel.register(selector, SelectionKey.OP_READ);
                            //提示
                            System.out.println(socketChannel.getRemoteAddress() + "上线了");
                        }

                        if (key.isReadable()) { // 通道发生read事件，或通道是可读的状态
                            readData(key);

                        }

                        // 删除当前的key，防止重复处理
                        keyIterator.remove();
                    }

                }else {
//                    System.out.println("等待中。。。");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //读取客户端消息
    private void readData(SelectionKey selectionKey){
        // 定义socketChannel
        SocketChannel socketChannel = null;

        // 得到channel
       socketChannel = (SocketChannel) selectionKey.channel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        try {
            int read = socketChannel.read(byteBuffer);
            // 根据read()返回值判断是否读到数据
            if (read > 0) {
                String string = new String(byteBuffer.array());
                System.out.println("from 客户端" + string );

                // 向其他客户端（去掉自己）转发消息
                sendInfoToOtherClients(string,socketChannel);
            }
        } catch (IOException e) {
            try {
                System.out.println(socketChannel.getRemoteAddress() + "离线了");
                // 取消注册
                selectionKey.cancel();
                // 关闭通道
                socketChannel.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

    // 转发消息给其他客户端
    private void sendInfoToOtherClients(String msg,SocketChannel self) throws IOException {
        System.out.println("服务器转发消息");
        System.out.println("服务器转发消息线程：" + Thread.currentThread().getName());
        for (SelectionKey selectionKey : selector.keys()) {
            Channel targetChannel = selectionKey.channel();

            // 排除自己
            if (targetChannel instanceof SocketChannel && !targetChannel.equals(self)) {
                ((SocketChannel) targetChannel).write(ByteBuffer.wrap(msg.getBytes()));
            }
        }
    }

    public static void main(String[] args) {
        new GroupChartServer().listen();
    }
}
